<template>
  <div class="system-role-container layout-padding">
    <el-card shadow="hover" class="mb5" body-class="pa5">
      <div class="system-user-search flex">
        <div class="flex align-center">
          <el-tooltip
            v-if="formColumns?.length"
            effect="dark"
            :content="isFilterCollapse ? '收起筛选' : '展开筛选'"
            placement="left"
          >
            <el-button :icon="Filter" circle @click="onFilterCollapse" />
          </el-tooltip>
          <el-button
            :loading="loading"
            :icon="FolderAdd"
            type="success"
            @click="onOpenForm('add')"
            class="ml5"
          >
            新增
          </el-button>
          <el-button :loading="loading" type="info" @click="onActionExportJson()" class="ml5"
            >导出JSON</el-button
          >
          <el-button :loading="loading" type="warning" @click="onActionImportJson()" class="ml5"
            >导入JSON</el-button
          >
        </div>
        <div class="ml-auto">
          <el-tooltip v-if="isFilterCollapse" effect="dark" content="清空筛选" placement="left">
            <el-button
              :disabled="isFilter"
              :icon="Delete"
              circle
              :loading="loading"
              @click="onReset"
            />
          </el-tooltip>
          <el-button
            v-if="isFilterCollapse"
            type="primary"
            :icon="Search"
            :loading="loading"
            @click="emitFetch"
          >
            查询
          </el-button>
          <el-button v-else :icon="Refresh" :loading="loading" @click="emitFetch">刷新</el-button>
        </div>
      </div>
      <div v-if="formColumns?.length && isFilterCollapse" class="mt5">
        <el-row :gutter="10">
          <el-col
            v-for="(form, index) in formColumns"
            :key="index"
            :xs="24"
            :sm="12"
            :md="6"
            :lg="6"
            :xl="4"
            class="mt5"
          >
            <el-input
              v-if="form.type === 'string'"
              v-model="params[form.prop]"
              :placeholder="`请输入${form.label}`"
              style="width: 100%"
              clearable
              class="custom-prepend"
              @keyup="onInput(form.prop)"
              @clear="onInput(form.prop)"
            >
              <template #prepend>{{ form.label }}</template>
            </el-input>
            <div
              v-else-if="['date', 'daterange', 'datetime'].includes(form.type)"
              class="flex custom-input"
            >
              <div class="el-input-group__prepend">{{ form.label }}</div>
              <el-date-picker
                v-model="params[form.prop]"
                :type="form.type"
                :placeholder="`请选择${form.label}`"
                :start-placeholder="form.type === 'daterange' ? '开始时间' : ''"
                :end-placeholder="form.type === 'daterange' ? '结束时间' : ''"
                style="width: 100%"
                clearable
              />
            </div>
            <div v-else-if="form.type === 'select'" class="flex custom-input">
              <div class="el-input-group__prepend">{{ form.label }}</div>
              <el-select
                v-model="params[form.prop]"
                :placeholder="`请选择${form.label}`"
                :multiple="form.multiple"
                style="width: 100%"
                clearable
              >
                <el-option
                  v-for="item in form.options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </div>
            <div v-else-if="form.type === 'boolean'" class="flex custom-switch">
              <div class="el-input-group__prepend">{{ form.label }}</div>
              <el-switch
                v-model="params[form.prop]"
                inline-prompt
                :active-icon="Check"
                :inactive-icon="Close"
              />
            </div>
            <div v-else-if="form.type === 'radio'" class="flex custom-switch">
              <div class="el-input-group__prepend">{{ form.label }}</div>
              <el-radio-group v-model="params[form.prop]">
                <el-radio v-for="(item, index) in form.options" :key="index" :label="item.value">
                  {{ item.label }}
                </el-radio>
              </el-radio-group>
            </div>
          </el-col>
        </el-row>
      </div>
    </el-card>
    <div class="layout-padding-auto layout-padding-view">
      <el-table
        ref="tableRef"
        :data="data"
        v-loading="loading"
        :row-key="rowKey"
        :tree-props="treeProps"
        style="width: 100%"
        :default-expand-all="treeProps?.defaultExpandAll || false"
      >
        <slot name="column"></slot>
      </el-table>
    </div>
  </div>
</template>

<script setup lang="ts" name="systemRole">
import { computed, onMounted, reactive, ref } from 'vue'
import { useRoute } from 'vue-router'
import { Filter, Search, Refresh, Check, Close, Delete, FolderAdd } from '@element-plus/icons-vue'
import { Local, Session } from '@/utils/storage'
import { clone } from 'xe-utils'
import { isObjectValueEqual } from '@/utils/arrayOperation'
import { ElMessage } from 'element-plus'
import { saveFile, readFile } from 'vxe-pc-ui'
import type { FormColumn, TableFormColumn, TableFormPagination } from '@/types/custom'
import { useBaseApi } from '@/api/base'

interface Props {
  data: any[]
  columns: TableFormColumn[]
  loading?: boolean
  total?: number
  pagination?: TableFormPagination
  formColumns?: FormColumn[]
  treeProps?: TypedAny
  rowKey?: string
}

const props = defineProps<Props>()

const emit = defineEmits(['input', 'open-form', 'fetch', 'update:loading'])

const { CustomRequest } = useBaseApi()

const tableRef = ref()
const route = useRoute()
const routeName = String(route.name)
// 分页
const tableFormPagination = ref<TableFormPagination>({
  page: 1,
  pageSize: 10
})
// 表单数据
const params = reactive<TypedAny>(Session.get('menu_form_title') || {})
// 展开筛选面板
const isFilterCollapse = ref(Local.get(`${routeName}_collapse`) || false)
// 初始值
let objectEqual = {}

// 是否筛选
const isFilter = computed(() => {
  return isObjectValueEqual(params, objectEqual)
})

const onInput = (prop: string) => {
  emit('input', params[prop])
  Session.set('menu_form_title', params)
}

/**
 * 导出JSON
 */
const onActionExportJson = () => {
  const rows = tableRef.value.getSelectionRows()
  if (!rows.length) return ElMessage.warning('未勾选')
  const config = {
    url: '/api-base/Business/ExportBusinessRowAndUi',
    method: 'post',
    params: {},
    data: {
      rows: rows.map((v: TypedAny) => v.id)
    }
  }
  emit('update:loading', true)
  CustomRequest(config)
    .then(({ data }) => {
      saveFile({
        filename: '菜单管理',
        type: 'json',
        content: JSON.stringify({ rows: data })
      })
      ElMessage.success('导出JSON成功')
    })
    .finally(() => {
      emit('update:loading', false)
    })
}

/**
 * 导入JSON
 */
const onActionImportJson = async () => {
  const { file } = await readFile({ multiple: false })
  if (file) {
    const reader = new FileReader()
    reader.onload = ({ target }: ProgressEvent<FileReader>) => {
      if (target && target.result) {
        try {
          const jsonContent = JSON.parse(String(target.result))
          const config = {
            url: '/api-base/Business/ImportBusinessRowAndUi',
            method: 'post',
            params: {},
            data: jsonContent
          }
          emit('update:loading', true)
          CustomRequest(config)
            .then(() => {
              ElMessage.success('导入JSON成功')
              emitFetch()
            })
            .finally(() => {
              emit('update:loading', false)
            })
        } catch (e) {
          ElMessage.warning('文件处理失败')
        }
      }
    }
    reader.readAsText(file)
  }
}

/**
 * 打开表格
 * @param type
 * @param row
 */
const onOpenForm = (type: string, row?: any) => {
  emit('open-form', type, row)
}

/**
 * 筛选显示隐藏
 */
const onFilterCollapse = () => {
  isFilterCollapse.value = !isFilterCollapse.value
  Local.set(`${routeName}_collapse`, isFilterCollapse.value)
}

/**
 * 查询
 */
const emitFetch = () => {
  emit('fetch', params)
}

/**
 * 重置
 */
const onReset = () => {
  props.formColumns?.forEach((v) => {
    if (v.type === 'boolean') {
      params[v.prop] = params[v.prop] || false
    } else if (v.type === 'string') {
      params[v.prop] = params[v.prop] || ''
    } else if (v.type === 'select') {
      params[v.prop] = params[v.prop] || v.multiple ? [] : ''
    } else if (v.type === 'daterange') {
      params[v.prop] = params[v.prop] || []
    } else {
      params[v.prop] = params[v.prop] || undefined
    }
  })
  objectEqual = clone(params, true)
}

onMounted(() => {
  if (props.pagination) {
    tableFormPagination.value.page = props.pagination.page
    tableFormPagination.value.pageSize = props.pagination.pageSize
  }
  onReset()
})
</script>
